<!DOCTYPE HTML PUBLIC "-//W4C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>ebay Map View</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <!-- backbone.js related libraries -->
        <script type="text/javascript" src="./resources/js/lib/jquery.js"></script>
        <script type="text/javascript" src="./resources/js/lib/underscore.js"></script>
        <script type="text/javascript" src="./resources/js/lib/backbone.js"></script>
        <!-- Bing Map API -->
        <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>

        <!-- template for the search box, used by underscore.js -->
        <script type="text/template" id="search_template">
            <!-- <label>Search</label> -->
            <input type="text" id="search_input" />
            <input type="button" id="search_button" value="Search" />
        </script>
    </head>

    <body>
        <div id="search_container" style="position:relative; text-align:center; width:800px; margin: 0 auto;"></div>
        <div style="position: relative; width: 1000px; height: 600px;margin: 0 auto; margin-top:10px;">
        <div id='bing_map_container' style="position:absolute; z-index:0;left:0px; right:0px; width:1000px; height:600px;margin: 0 auto;"></div>
        <div id='loading' style="display:none;position:absolute;z-index:1;left:0px; right:0px; width:1000px; height:600px;margin: 0 auto;text-align:center;vertical-align:middle;">
            <img src="./resources/image/loading.gif" style="position:absolute;top:40%;left:50%;" alt="loading..." />
        </div>
        </div>

        <!-- define models/views/comm_utils/html_templates etc. -->
        <script type="text/javascript" src="./resources/js/modelview.js"></script>

        <!-- main logic -->
        <script type="text/javascript">
            var createBingMapPinInfoBox = function() {
                var pinInfoBox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0),
                    {title: "dummy infobox",
                     description: 'dummy infobox', 
                     visible: false, 
                     offset: new Microsoft.Maps.Point(0,0)
                    });
                return pinInfoBox;
            };
            var SearchView = Backbone.View.extend({
                initialize : function() {
                    _.bindAll(this, "fetchSuccessAndUpdateMapView", "fetchFailed",
                            "showHoverInfoBox", "updateHoverInfoBox", "hideHoverInfoBox");
                    this.render();
                },
                model: new FindByKeywordsModel(),
                bingMap: createBingMap(),
                // this infobox shows when the mouse is over one pin.
                lastX: 0, lastY: 0,
                hoverInfoBoxVisible: false,
                hoverInfoBox: createBingMapPinInfoBox(),

                render : function() {
                    // compile the template using underscore.js
                    var template = _.template($("#search_template").html(), {});
                    // load the compiled html into the Backbone's element
                    this.$el.html(template);
                },
                events : {
                    "click #search_button" : "searchButtonPressed",
                    'keypress #search_input' : 'searchBoxKeyPressed',
                },
                searchButtonPressed : function(e) {
                    // search button clicked
                    var keywords = $("#search_input").val();
                    this.doSearch(keywords);
                },
                searchBoxKeyPressed: function(e) {
                    // enter pressed in search box
                    if (e.which !== 13)
                        return;
                    var keywords = $(e.target).val();
                    this.doSearch(keywords);
                },
                showBusy : function() {
                    $("#loading").show();
                    $("#bing_map_container").css({ opacity: 0.5 });
                },
                showBusyCompleted : function() {
                    $("#loading").hide();
                    $("#bing_map_container").css({ opacity: 1.0 });
                },
                doSearch : function(keywords) {
                    if (!keywords) {
                        alert("empty keywords.");
                        return;
                    }
                    // !!! important, issue request to back-end RESTful API.
                    // clear entities first.
                    this.bingMap.entities.clear(); 
                    this.showBusy();
                    this.model.set( { "id": keywords } );
                    this.model.fetch({
                         success: this.fetchSuccessAndUpdateMapView,
                    });
                },
                fetchSuccessAndUpdateMapView: function() {
                    // !!! important, handle back-end RESTful API response.
                    this.showBusyCompleted();
                    this.bingMap.entities.push(this.hoverInfoBox);
                    var items = this.model.get("items");
                    for (var i = 0; i < items.length; i++) { 
                        var item = items[i];
                        var location = new Microsoft.Maps.Location(item.latitude, item.longitude); 
                        var pin= new Microsoft.Maps.Pushpin(location,
                            {icon:"resources/image/push_pin_small.png", height:20, width:13, draggable: false});
                        pin.item = item; // attach this item to the pin itself.
                        this.bingMap.entities.push(pin); 
                        
                        Microsoft.Maps.Events.addHandler(pin, 'mouseover', this.showHoverInfoBox);
                        Microsoft.Maps.Events.addHandler(this.bingMap, 'mouseover', this.updateHoverInfoBox);
                    }
                },
                showHoverInfoBox: function(e) {
                    // note down current location
                    this.lastX = e.pageX;
                    this.lastY = e.pageY;

                    if (e.targetType != "pushpin")
                        return;
                    var pin = e.target;
                    var item = e.target.item;
                    var itemTitle = "<a href='{itemUrl}' target='_blank' style='font-size:10px'>{itemTitle}</a>";
                    itemTitle = itemTitle.replace("{itemUrl}", item.itemUrl).replace("{itemTitle}", item.title);
                    //var desc = "Seller: {seller}<br/>Positive Feedback: {positiveFeedback}%<br/>"
                    var desc = ""
                        + "Category: {primaryCategory}, {secondaryCategory}<br/>" + "Price: {currentPrice}";
                    //desc = desc.replace("{seller}", item.sellerUserName);
                    //desc = desc.replace("{positiveFeedback}", item.positiveFeedback);
                    desc = desc.replace("{primaryCategory}", item.primaryCategory)
                    desc = desc.replace("{secondaryCategory}", item.secondaryCategory);
                    desc = desc.replace("{currentPrice}", item.currentPrice);
                    this.hoverInfoBox.setLocation(e.target.getLocation());
                    this.hoverInfoBox.setOptions({
                        title: itemTitle,
                        description: desc,
                        width:300, height:120,
                        visible:true });
                    this.hoverInfoBoxVisible = true;
                },
                updateHoverInfoBox: function(e) {
                    if (!this.hoverInfoBoxVisible) return;
                    var currX = e.pageX;
                    var currY = e.pageY;
                    var dist = Math.abs(currX - this.lastX) + Math.abs(currY - this.lastY);
                    if (dist > 10) {
                        this.hideHoverInfoBox();
                    }
                },
                hideHoverInfoBox: function() {
                    this.hoverInfoBox.setOptions({ visible:false });
                    this.hoverInfoBoxVisible = false;
                },
                fetchFailed: function() {
                    alert("Failed to call back-end RESTful API.");
                }
            });
            // create a View, also bind event handlers.
            var search_view = new SearchView({ el: $("#search_container") });
        </script>
    </body>
</html>

